![]() |
WOLF core
WOLF: A Modular Estimation Framework for Robotics
|
Singleton template factory. More...
#include <core/common/factory.h>
Public Types | |
| typedef TypeBase(* | CreatorCallback) (TypeInput... _input) |
Public Member Functions | |
| std::string | getClass () const |
| Factory (const Factory &)=delete | |
| void | operator= (Factory const &)=delete |
Static Public Member Functions | |
| static bool | registerCreator (const std::string &_type, CreatorCallback createFn) |
| static bool | unregisterCreator (const std::string &_type) |
| static bool | isCreatorRegistered (const std::string &_type) |
| static TypeBase | create (const std::string &_type, TypeInput... _input) |
| static void | printAddress () |
| static void | printCallbacks () |
| static std::list< std::string > | getRegisteredKeys () |
Singleton template factory.
This template class implements a generic factory as a singleton.
| TypeBase | base type of all the objects created by the factory |
| TypeInput | variadic type for the input arguments. |
The class is templatized on the class of the produced objects, TypeBase. The produced objects are always of a class deriving from TypeBase. The returned data is an object of type TypeBase. If you want a shared pointer to an object, then TypeBase must be the desired shared pointer.
From now on we will assume that a typedef is defined: std::shared_ptr<Type> as TypePtr.
For example, you may use as TypeBase the following types:
LandmarkBasePtr to themSensorBasePtr to themXxxBasePtr to them.factory_landmark.h, factory_map.h, Once specialized, this factory can create objects of classes deriving from TypeBase.
For example, if you want to make a Landmark factory, set TypeBase = LandmarkBasePtr.
Then, the factory will create specific landmarks deriving from LandmarkBase.
The specific type of landmark (e.g. LandmarkCorner2d, LandmarkAHP, LandmarkPolyline2d, etc) is indicated by a
string that we call TYPE in this documentation.
Specific object creation is invoked by the method create(TYPE, params ... ), where
The methods to create specific objects are called creators. Creators must be registered to the factory before they can be invoked for object creation.
This documentation shows you how to:
We use a std::string with literally the same text as the derived class name, e.g.:
"SensorCamera""SensorLaser2d""LandmarkPolyline2d"The first thing to know is that we have defined typedefs for the templates that we are using. For example:
Second to know, the Factory class is a singleton: it can only exist once in your application. To access it, we internally use the static method get(),
\code Factory<MyTypeBase, MyTypeInput>::get() \endcode
but this is a private method.
The interesting methods are designed static, and are the ones responsible for accessing the Factory instance via .get().
You must therefore call the methods you like statically, e.g. to create a landmark, you use:
\code FactoryLandmark::create(TYPE, args...); // see below for creating objects ... \endcode
The method LandmarkPolyline2d::create(...) exists in the LandmarkPolyline2d class as a static method. All these XxxXxx::create() methods need to have exactly the same API, regardless of the object type. The API puts into play the two template parameters:
This API includes elements defined as TypeInput, which might be one or more inputs.
For the two examples introduced before, the corresponding creators would be:
\code static StateBlockPtr create(const Eigen::VectorXd& _state, bool _fixed) static LandmarkBasePtr create(const YAML::Node& _lmk_yaml_node) \endcode
See further down for an implementation example.
Prior to invoking the creation of an object of a particular TYPE, you must register the creator for this type into the factory.
Registering object creators into the factory is done through registerCreator(). You provide an object TYPE string (above), and a pointer to a static method that knows how to create your specific object, e.g.:
\code
FactoryLandmark::registerCreator("LandmarkPolyline2d", LandmarkPolyline2d::create);
\endcode
Currently, registering is performed in specific source files, object_xxxx.cpp. For example, in sensor_camera_yaml.cpp we find the line:
\code
const bool registered_camera_intr = FactoryParamsSensor::registerCreator("ParamsSensorCamera",
createParamsSensorCamera);
which is a static invocation (i.e., it is placed at global scope outside of the ParamsSensorCamera class).
Therefore, at application level, all objects that have a .cpp file compiled are automatically registered.
The method unregisterCreator() unregisters the ObjectXxx::create() method. It only needs to be passed the string of the object type.
\code
Factory<MyTypeBase, MyTypeInput>::unregisterCreator("ParamsSensorCamera");
\endcode
Note: Prior to invoking the creation of a object of a particular type, you must register the creator for this type into the factory.
To create e.g. a LandmarkPolyline2d from a YAML node you type:
\code
LandmarkBasePtr lmk_ptr = Factory<LandmarkBasePtr, YAML::Node>::create("LandmarkPolyline2d", lmk_yaml_node);
\endcode
or even better, make use of the convenient typedefs:
\code
LandmarkBasePtr lmk_ptr = FactoryLandmark::create("LandmarkPolyline2d", lmk_yaml_node);
\endcode
You can find this code in the landmark_polyline_2d.cpp file.
You can find this code in the landmark_polyline_2d.cpp file.
src/examples/test_map_yaml.cpp.| typedef TypeBase(* wolf::Factory< TypeBase, TypeInput >::CreatorCallback) (TypeInput... _input) |
|
delete |
|
inlinestatic |
|
inline |
|
inlinestatic |
|
inlinestatic |
|
delete |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |